home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
001-025
/
scopedisk24
/
qrt14src
/
stack.c
< prev
Wrap
C/C++ Source or Header
|
1995-03-18
|
9KB
|
343 lines
/*******************************************************
stacks and queues
*******************************************************/
#include "qrt.h"
#include "pattern.h"
/* #define STACKDEBUG 1 */
char *malloc();
/**********************************************************
Calls the pre-computing routine for each object in
the object tree. The pre-computing routines figure
out some sub-expressions that don't change with
different calls to the intersection routines.
**********************************************************/
Do_Precomp(node)
OBJ_PTR node;
{
# ifdef STACKDEBUG
printf("DOPRECOMP: type = %d\n", node->type);
# endif
(*(ObjData[node->type].PreComp))(node); /* precompute */
if (node->child != NULL) { /* node has children ? */
# ifdef ROBUST
if (node->type != BBOX) Error(INTERNAL_ERROR,802);
# endif
Do_Precomp(node->child);
}
if (node->nextobj != NULL) {
Do_Precomp(node->nextobj);
}
}
/**********************************************************
Assigns bounding box values for entire object tree.
This must be called once before any ray-tracing is done.
**********************************************************/
Make_Bbox(node)
OBJ_PTR node;
{
OBJ_PTR tnode;
VECTOR v1,v2;
# ifdef STACKDEBUG
printf("MAKEBBOX\n");
# endif
if (node->child!=NULL) { /* node has children ? */
# ifdef ROBUST
if (node->type!=BBOX) Error(INTERNAL_ERROR,801);
# endif
Make_Bbox(node->child);
}
if (node->nextobj!=NULL) { /* node has siblings ? */
Make_Bbox(node->nextobj);
}
if (node->type==BBOX) {
tnode=node->child;
node->lower.x=node->lower.y=node->lower.z= 3e30;
node->upper.x=node->upper.y=node->upper.z= -3e30;
while (tnode!=NULL) {
(*(ObjData[tnode->type].FindBbox))(&v1,&v2,tnode);
node->lower.x=MIN(node->lower.x,v1.x);
node->lower.y=MIN(node->lower.y,v1.y);
node->lower.z=MIN(node->lower.z,v1.z);
node->upper.x=MAX(node->upper.x,v2.x);
node->upper.y=MAX(node->upper.y,v2.y);
node->upper.z=MAX(node->upper.z,v2.z);
# ifdef STACKDEBUG
printf("MAKEBBOX: v1 x,y,z = %f %f %f\n",
node->lower.x,node->lower.y,node->lower.z);
printf(" v2 x,y,z = %f %f %f\n",
node->upper.x,node->upper.y,node->upper.z);
# endif
tnode=tnode->nextobj;
}
}
}
/**********************************************************
Returns pointer to pattern structure given name, or
null if not found.
**********************************************************/
PATTERN_PTR find_pat(name)
char *name;
{
PATTERN_PTR pat;
pat=THEWORLD.patlist;
while (pat!=NULL) {
if (strcmp(name,pat->name)==0) return(pat);
pat=pat->sibling;
}
return(NULL);
}
/**********************************************************
Allocates a new pattern structure and returns a
pointer to it.
**********************************************************/
PATTERN_PTR new_pat()
{
PATTERN_PTR pat;
if ((pat=(PATTERN_PTR)malloc(sizeof(PATTERN)))==NULL)
Error(MALLOC_FAILURE,802);
pat->name = NULL;
pat->child =
pat->sibling =
pat->link = NULL;
return(pat);
}
/**********************************************************
Allocates a new object structure, stuffs most of
its information fields, and returns a pointer to it.
**********************************************************/
OBJ_PTR new_obj(type,loc,v1,v2,v3,cinfo,pattern,remove,name,
upper, lower, cterm, xmult, ymult)
VECT_PTR loc, v1, v2, v3, upper, lower;
CINFO_PTR cinfo;
PATTERN_PTR pattern, remove;
float cterm, xmult, ymult;
char *name;
{
OBJ_PTR obj;
if ((obj=(OBJ_PTR)malloc(sizeof(OBJ_STRUCT)))==NULL)
Error(MALLOC_FAILURE,803);
obj->type=type; /* copy info */
VectEQ(&(obj->loc),loc);
VectEQ(&(obj->vect1),v1);
VectEQ(&(obj->vect2),v2);
VectEQ(&(obj->vect3),v3);
VectEQ(&(obj->lower),lower);
VectEQ(&(obj->upper),upper);
obj->cterm = cterm;
obj->xmult = xmult;
obj->ymult = ymult;
obj->name = name;
copy_colorinfo(&(obj->cinfo),cinfo); /* colorinfo */
obj->nextobj = obj->child = NULL; /* no relatives */
obj->pattern = pattern;
obj->remove = remove;
return(obj);
}
/**********************************************************
Generates an empty line
**********************************************************/
OBJ_PTR new_line() {
CINFO cinfo;
VECTOR loc,v1,v2,v3, upper, lower;
OBJ_PTR line;
VectEqZero(&loc);
VectEqZero(&v1);
VectEqZero(&v2);
VectEqZero(&v3);
VectEqZero(&upper);
VectEqZero(&lower);
line=new_obj(LINE,&loc,&v1,&v2,&v3,&cinfo,NULL,NULL,NULL,
&upper,&lower,(float)0.0,(float)0.0,(float)0.0);
line->flag = FALSE;
return(line);
}
/**********************************************************
Adds a lamp to the world
**********************************************************/
add_lamp(object) /* add a lamp to the world */
OBJ_PTR object;
{
object->nextobj=THEWORLD.lamps;
THEWORLD.lamps=object;
}
/**********************************************************
Debugging routine to print object structure
MAY BE WRONG BY NOW
**********************************************************/
#ifdef STACKDEBUG
print_obj(obj) /* display object */
OBJ_PTR obj;
{
printf("OBJECT : type: ");
switch (obj->type) {
case LINE: printf("LINE\n"); break;
case SPHERE: printf("SPHERE\n"); break;
case PARALLELOGRAM: printf("PARALLELOGRAM\n"); break;
case TRIANGLE: printf("TRIANGLE\n"); break;
case LAMP: printf("LAMP\n"); break;
case OBSERVER: printf("OBSERVER\n"); break;
case GROUND: printf("GROUND\n"); break;
case SKY: printf("SKY\n"); break;
case BBOX: printf("BBOX\n"); break;
case RING: printf("RING\n"); break;
case QUADRATIC: printf("QUADRATIC\n"); break;
default: printf("Unknown!\n"); break;
}
printf(" loc : %f, %f, %f\n",
(obj->loc.x),
(obj->loc.y),
(obj->loc.z));
printf(" vect1 : %f, %f, %f\n",
(obj->vect1.x),
(obj->vect1.y),
(obj->vect1.z));
printf(" vect2 : %f, %f, %f\n",
(obj->vect2.x),
(obj->vect2.y),
(obj->vect2.z));
printf(" vect3 : %f, %f, %f\n",
(obj->vect3.x),
(obj->vect3.y),
(obj->vect3.z));
}
#endif
/**********************************************************
Prints some interesting statistics
**********************************************************/
World_Stats() {
printf("World Statistics:\n");
printf(" Objects: %4d\n",THEWORLD.objcount);
printf(" Lamps: %4d\n",THEWORLD.lampcount);
printf(" Intersect tests : %-8ld\n", THEWORLD.intersect_tests);
printf(" Total Intersections : %-8ld\n",(THEWORLD.ray_intersects+
THEWORLD.bbox_intersects));
printf(" Object intersections : %-8ld\n", THEWORLD.ray_intersects);
printf(" Bbox intersections : %-8ld\n", THEWORLD.bbox_intersects);
printf(" Rays traced : %-8ld\n",(THEWORLD.primary_traced+
THEWORLD.to_lamp+
THEWORLD.refl_trans));
printf(" Primary : %-8ld\n", THEWORLD.primary_traced);
printf(" To lamps : %-8ld\n", THEWORLD.to_lamp);
printf(" Refl. or Trans. : %-8ld\n", THEWORLD.refl_trans);
printf(" Pattern match checks : %-8ld\n", THEWORLD.pattern_matches);
printf("\n Data sent to: %s\n\n",THEWORLD.outfile);
}
/**********************************************************
Open file, and send image size
**********************************************************/
Open_File() {
if ((THEWORLD.filept=fopen(THEWORLD.outfile,"w"))==NULL)
Error(FILE_ERROR,804);
fputc((unsigned char)(XSIZE & 0xff),THEWORLD.filept);
fputc((unsigned char)(XSIZE >> 8), THEWORLD.filept);
fputc((unsigned char)(YSIZE & 0xff),THEWORLD.filept);
fputc((unsigned char)(YSIZE >> 8), THEWORLD.filept);
}
/**********************************************************
Close file
**********************************************************/
Close_File() {
if (fclose(THEWORLD.filept)) Error(FILE_ERROR,805);
}